package torres.entity;
import java.util.ArrayList;
import java.util.LinkedHashSet;

import torres.ability.Ability;
import torres.ability.AbilityManager;
import torres.action.Effect;
import torres.fileIO.BasicContainer;
import torres.fileIO.ClassContainer;
import torres.item.WeaponType;



/**
 * @author Torres
 * A specific Occupation that specializes in hand-to-hand combat.
 * The primary stat of this Occupation is Strength.
 */

public class Smasher implements Occupation {
	private LinkedHashSet<Ability> smasherAbilityList;
	private LinkedHashSet<Ability> smasherAttackList;
	private final Stat smasherPrimaryStat = Stat.STRENGTH;
	private final Job job = Job.SMASHER;
	private double smasherStrengthMultiplier;
	private double smasherAgilityMultiplier;
	private double smasherIntellectMultiplier;
	private int oneHandedSkill;
	private int twoHandedSkill;
	private int brawlSkill;
	private final String name = "Smasher";
	
	/**
	 * Creates a default Smasher.
	 */
	public Smasher() { // Default Constructor
//		smasherAbilityList = new ArrayList<Ability>();
		smasherStrengthMultiplier = 1.3;
		smasherAgilityMultiplier = 1.15;
		smasherIntellectMultiplier = 1.15;
		smasherAbilityList = new LinkedHashSet<Ability>();
		smasherAttackList = new LinkedHashSet<Ability>(3);	}
	
	/**
	 * Creates a new Smasher with the specified values. 
	 * @param abilityList The ability list.
	 * @param strength The strength multiplier.
	 * @param agility The agility multiplier.
	 * @param intellect The intellect multiplier.
	 */
/*	public Smasher(List<Ability> abilityList, double strength, double agility, double intellect) {
	this.smasherAbilityList = abilityList;
		this.smasherStrengthMultiplier = strength;
		this.smasherAgilityMultiplier = agility;
		this.smasherIntellectMultiplier = intellect;
	}*/

	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getAgilityMultiplier()
	 */
	public double getAgilityMultiplier() {
		return smasherAgilityMultiplier;
	}

	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getIntellectMultiplier()
	 */
	public double getIntellectMultiplier() {
		return smasherIntellectMultiplier;
	}
	
	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getPrimaryStat()
	 */
	@Override
	public Stat getPrimaryStat() {
		// TODO Auto-generated method stub
		return null;
	}
	
	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getStrengthMultiplier()
	 */
	public double getStrengthMultiplier() {
		return smasherStrengthMultiplier;
	}

	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getAbilityList()
	 */
	public LinkedHashSet<Ability> getAbilityList() {
		return smasherAbilityList;
	}
	
	/**
	 * Sets oneHandedSkill. Deals with Smashers effectiveness with oneHanded Weapons.
	 * @param oneHandedSkill the new oneHandedSkill value to set
	 */
	public void setOneHandedSkill(int oneHandedSkill) {
		this.oneHandedSkill = oneHandedSkill;
	}

	/**
	 * Return oneHandedSkill.
	 * @return the oneHandedSkill
	 */
	public int getOneHandedSkill() {
		return oneHandedSkill;
	}

	/**
	 * Sets twoHandedSkill. Deals with Smashers effectiveness with oneHanded Weapons.
	 * @param twoHandedSkill the new twoHandedSkill value to set
	 */
	public void setTwoHandedSkill(int twoHandedSkill) {
		this.twoHandedSkill = twoHandedSkill;
	}

	/**
	 * Returns twoHandedSkill.
	 * @return the twoHandedSkill
	 */
	public int getTwoHandedSkill() {
		return twoHandedSkill;
	}

	/**
	 * Sets brawlSkill. Deals with Smashers effectiveness with bare hands.
	 * @param brawlSkill the new brawlSkill value to set
	 */
	public void setBrawlSkill(int brawlSkill) {
		this.brawlSkill = brawlSkill;
	}

	/**
	 * Returns brawlSkill.
	 * @return the brawlSkill
	 */
	public int getBrawlSkill() {
		return brawlSkill;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return name;
	}
	
	/* (non-Javadoc)
	 * @see torres.entity.Occupation#getJob()
	 */
	@Override
	public Job getJob() {
		return job;
	}

	/* (non-Javadoc)
	 * @see torres.fileIO.Saveable#save()
	 */
	@Override
	public ClassContainer save() {
		
		ClassContainer curClass = new ClassContainer("Job");
		ClassContainer curStructure = new ClassContainer("AbilityList");
		/*if(smasherAbilityList!=null) {
			for(Ability ability: smasherAbilityList) {
				curStructure.addProperty(ability.save());
			}
		}*/
		curClass.addProperty(curStructure);
		
		curClass.addProperty(new BasicContainer("smasherStrengthMultiplier", smasherStrengthMultiplier));
		curClass.addProperty(new BasicContainer("smasherAgilityMultiplier", smasherAgilityMultiplier));
		curClass.addProperty(new BasicContainer("smasherIntellectMultiplier", smasherIntellectMultiplier));
		curClass.addProperty(new BasicContainer("oneHandedSkill", oneHandedSkill));
		curClass.addProperty(new BasicContainer("twoHandedSkill", twoHandedSkill));
		curClass.addProperty(new BasicContainer("brawlSkill", brawlSkill));
		
		return curClass;
	}

	/* (non-Javadoc)
	 * @see torres.fileIO.Saveable#load(torres.fileIO.ClassContainer)
	 */
	@Override
	public void load(ClassContainer classContainer) {
		BasicContainer smasherStrengthMultiplierCont = (BasicContainer)classContainer.getProperty("smasherStrengthMultiplier");
		smasherStrengthMultiplier = Double.parseDouble((String)smasherStrengthMultiplierCont.getValue());
		BasicContainer smasherAgilityMultiplierCont = (BasicContainer)classContainer.getProperty("smasherAgilityMultiplier");
		smasherAgilityMultiplier = Double.parseDouble((String)smasherAgilityMultiplierCont.getValue());
		BasicContainer smasherIntellectMultiplierCont = (BasicContainer)classContainer.getProperty("smasherIntellectMultiplier");
		smasherIntellectMultiplier = Double.parseDouble((String)smasherIntellectMultiplierCont.getValue());
		BasicContainer oneHandedSkillCont = (BasicContainer)classContainer.getProperty("oneHandedSkill");
		oneHandedSkill = Integer.parseInt((String)oneHandedSkillCont.getValue());
		BasicContainer twoHandedSkillCont = (BasicContainer)classContainer.getProperty("twoHandedSkill");
		twoHandedSkill = Integer.parseInt((String)twoHandedSkillCont.getValue());
		BasicContainer brawlSkillCont = (BasicContainer)classContainer.getProperty("brawlSkill");
		brawlSkill = Integer.parseInt((String)brawlSkillCont.getValue());
		
	}

	/* (non-Javadoc)
	 * @see torres.entity.Occupation#updateAbilityList(int)
	 */
	@Override
	public void updateAbilityList(int level) {
		// TODO Auto-generated method stub
		AbilityManager.getInstance().updateAbilityList(smasherAbilityList, level, this.getJob());
		
	}
	
	/**
	 * Returns Smashers bonus with oneHanded weapons.
	 * @return One Handed Attack Multiplier of Smasher
	 */
	public int getOneHandedSkillBonus(){
		
		return (100 + (oneHandedSkill)); 
	}
	
	
	/**
	 * Returns Smashers bonus with twoHanded weapons.
	 * @return Two Handed Attack Multiplier of Smasher
	 */
	public int getTwoHandedSkillBonus(){
		
		return (70 + (twoHandedSkill));
	}
	
	/**
	 * Returns Smashers bonus with bare hands. 
	 * @return Brawl Attack Multiplier of Smasher
	 */
	public int getBrawlSkillBonus(){
		
		return (70 + (brawlSkill));
	}

	@Override
	public boolean allocateSkillPoint(Skill skill) {
		// TODO Auto-generated method stub
		switch(skill) {	
			case ONE_HANDED_WEAPON : 
				if(oneHandedSkill<35)
					this.oneHandedSkill++; 		
				else 
						return false;
				break;
			case TWO_HANDED_WEAPON : 
				if(twoHandedSkill<35)
					this.twoHandedSkill++;
				else 
					return false;
				break;
			case BRAWLING :
				if(brawlSkill<35)
					this.brawlSkill++; 
				else 
					return false;
				break;
			default : 
				System.err.println("Smasher.allocateSkillPoint(): " +
						"Skill point was not allocated. Skill: " + skill.toString());
				return false;
		}
		return true;
	}

	@Override
	public LinkedHashSet<String> retreiveSkillList(LinkedHashSet<String> skillList) {
		// TODO Auto-generated method stub
		skillList.add("One Handed Skill:\t\t\t" + this.oneHandedSkill);
		skillList.add("Two Handed Skill:\t\t\t" + this.twoHandedSkill);
		skillList.add("Brawling Skill:\t\t\t" + this.brawlSkill);
		return skillList;
	}

	@Override
	public LinkedHashSet<Skill> retreiveSkillEnumList(LinkedHashSet<Skill> hashSet) {
		hashSet.add(Skill.ONE_HANDED_WEAPON);
		hashSet.add(Skill.TWO_HANDED_WEAPON);
		hashSet.add(Skill.BRAWLING);
		return hashSet;
	}
	
	public void moveHook(Entity e) {
		//this method left intentionally (almost) blank 
	}

	/**
	 * @param smasherAttackList the smasherAttackList to set
	 */
	public void setAttackList(LinkedHashSet<Ability> smasherAttackList) {
		this.smasherAttackList = smasherAttackList;
	}

	/**
	 * @return the smasherAttackList
	 */
	public LinkedHashSet<Ability> getAttackList() {
		return smasherAttackList;
	}

	/**
	 * @return the smasherPrimaryStat
	 */
	public Stat getSmasherPrimaryStat() {
		return smasherPrimaryStat;
	}
	
	public boolean canEquip(WeaponType type) {
		return true;
	}
	
	public double applySkill(Effect e) {
		return 1.0;
	}
}
